using UnityEngine;
using System.Collections;
using System;

public class GameMaintainerSingleton : MonoBehaviour {

	public static GameMaintainerSingleton Instance { get; private set; }
	public int LifeLeft;
	public int MaxLife;
	public int Score;
	public int HighScore;
	private GameObject [] heartObjects;
	private GameObject [] sounds;
	private GameObject emptyHeartObject;
	private GameObject halfHeartObject;
	private GameObject fullHeartObject;
	public GameObject TheGame;
	public GameObject GameScripts;
	int width;
	int height;
	public int Difficulty;
	public int SoundVolume;
	public int MusicVolume;
	float worldX;
	float worldY;
	float ShakeTime = -1f;
	float StartedShakeTime = -1f;
	bool hasGameOvered = false;
	float gameOverTimer = 4f;
	float gameOverMaxTimer = 4f;
	float gameOverEffectsTimer = 1f;
	float gameOverMaxEffectsTimer = 1f;
	TextMesh gameOverTextMesh;
	Camera _cam;
	Camera cam {
		get {
			if (_cam == null) {
				_cam = (Camera)GameObject.Find ("Main Camera").GetComponent(typeof(Camera));
				return _cam;
			}
			else {
				return _cam;
			}
		}
		set {
			_cam = value;
		}
	}
	public bool FirstTimeUsage = true;

	float waitTime = 0f;
	int lastTime = 0;
	bool ifReady = false;
	bool displayedAdsOnce = false;
	bool triggerAdOpen = false;
	bool triggerAdClose = false;

	bool triggerInterstitialAdOpen = false;
	bool triggerInterstitialAdClose = false;

	public bool AndroidSocialActivated = false;

	TextMesh timeLeftText;
	public static event Action<bool> AdOpened;
	private bool isAdOpened = false;
	public bool IsAdOpened { get { return this.isAdOpened; } }

	private AdMobPlugin bannerView;

	public bool ClickEvent = false;
	public bool AlreadyClicked = false;
	public bool ClickDown = false;
	public bool ClickUp = false;
	public bool Moved = false;
	public bool BackButtonPressed = false;

	public int StartFingerId = -1;
	public int CurrentFingerId = -1;
	
	public Vector2 Pos = Vector2.zero;
	public Vector2 ClickDownPos = Vector2.zero;

	public bool IsPausing = false;
	public bool IsUnpausing = false;
	public bool IsPaused = false;
	private float PauseTimer = 1f;
	private float PauseStartTimer = 1f;
	private System.DateTime PauseTimeStart;
	private System.DateTime PauseTimeNow;

	public string DebugText;
	bool StartedAdsOnce = false;
#if UNITY_IPHONE && !UNITY_EDITOR
	private ADBannerView iosBannerView;
#endif

	public bool IsInSpriteBounds(SpriteRenderer rendererToCheck, Vector2 positionToCheck) {
		Vector3 minBounds = Camera.main.WorldToScreenPoint(rendererToCheck.bounds.min);
		Vector3 maxBounds = Camera.main.WorldToScreenPoint(rendererToCheck.bounds.max);
		if (positionToCheck.x >= minBounds.x && positionToCheck.x <= maxBounds.x && positionToCheck.y >= minBounds.y && positionToCheck.y <= maxBounds.y) {
			//Application.LoadLevel(1);
			return true;
		}
		return false;
	}
	
	public bool IsInSpriteX(SpriteRenderer rendererToCheck, Vector2 positionToCheck, int threshold) {
		Vector3 minBounds = Camera.main.WorldToScreenPoint(rendererToCheck.bounds.min);
		Vector3 maxBounds = Camera.main.WorldToScreenPoint(rendererToCheck.bounds.max);
		if (positionToCheck.x >= minBounds.x - threshold && positionToCheck.x <= maxBounds.x + threshold) {
			//Application.LoadLevel(1);
			return true;
		}
		return false;
	}
	
	public bool IsInSpriteY(SpriteRenderer rendererToCheck, Vector2 positionToCheck, int threshold) {
		Vector3 minBounds = Camera.main.WorldToScreenPoint(rendererToCheck.bounds.min);
		Vector3 maxBounds = Camera.main.WorldToScreenPoint(rendererToCheck.bounds.max);
		if (positionToCheck.y >= minBounds.y - threshold && positionToCheck.y <= maxBounds.y + threshold) {
			//Application.LoadLevel(1);
			return true;
		}
		return false;
	}

	public void ScreenShake(float time) {
		Instance.StartedShakeTime = time;
		Instance.ShakeTime = time;
	}

	public void CheckAndPlaySound(int sound) {
		if (Instance.sounds == null) {
			Instance.LoadSounds();
		}
		if (Instance.sounds [sound] == null) {
			Instance.LoadSounds();
		}
		Instance.sounds [sound].audio.Play ();
	}

	public void CheckAndPlaySound(int sound, bool kill) {
		if (Instance.sounds == null) {
			Instance.LoadSounds();
		}
		if (Instance.sounds [sound] == null) {
			Instance.LoadSounds();
		}
		//Instance.sounds [sound].audio.Play ();
		GameObject objSound = (GameObject)Instantiate (Instance.sounds [sound]);
		SoundKillAfterPlay killScript = (SoundKillAfterPlay)objSound.GetComponent (typeof(SoundKillAfterPlay));
		killScript.StartPlaying = true;
	}

	public void PlayBeeHurtSound() {
		Instance.CheckAndPlaySound (0);
	}

	public void PlayBeeEnterSound() {
		Instance.CheckAndPlaySound (1);
	}

	public void PlayHurtSound() {
		Instance.CheckAndPlaySound (2);
	}

	public void PlayLifeUpSound() {
		Instance.CheckAndPlaySound (3);
	}

	public void PlayScoreSound() {
		Instance.CheckAndPlaySound (4);
	}
	
	public void PlayFlapSound() {
		Instance.CheckAndPlaySound (5,true);
	}

	public void PlayBombTickSound() {
		Instance.CheckAndPlaySound (6);
	}

	void AddPoints(float timeLeft) {
		Instance.Score += System.Convert.ToInt32 (timeLeft);
		Instance.UpdateHighScoreDuringGame ();
	}

	void UpdateHighScoreDuringGame() {
		if (Instance.Score >= Instance.HighScore) {
			Instance.HighScore = Instance.Score;
		}
	}

	void UpdateHighScoreOnGameOver() {
		if (Instance.Score >= Instance.HighScore) {
			Instance.HighScore = Instance.Score;
			Instance.SetHighScore();
		}
	}

	public void GetHighScore() {
		Instance.HighScore = PlayerPrefs.GetInt ("HighScore"+Instance.Difficulty);
	}

	void SetHighScore() {
		// I do some paranoid checking here to try and not overwrite the high score
		// with a zero if there was some unforeseen bug as has happened before.
		int tempHighScore = PlayerPrefs.GetInt ("HighScore"+Instance.Difficulty);
		int currentHighScore = Instance.HighScore;

		if (currentHighScore > tempHighScore) {
			PlayerPrefs.SetInt ("HighScore"+Instance.Difficulty, currentHighScore);
			if (Application.platform == RuntimePlatform.Android) {
				bool canPost = false;
				if (Social.localUser.authenticated) {
					string leaderBoardID = "";
					if (Instance.Difficulty == 0) {
						leaderBoardID = "CgkIh9beq80REAIQAA";
					}
					else if (Instance.Difficulty == 1) {
						leaderBoardID = "CgkIh9beq80REAIQAQ";
					}
					else if (Instance.Difficulty == 2) {
						leaderBoardID = "CgkIh9beq80REAIQAg";
					}
					else {
						
					}
					if (leaderBoardID != "") {
						Social.ReportScore(currentHighScore,leaderBoardID,(bool success) => {
							
						});
					}
				}
				else {
					Social.localUser.Authenticate((bool authenticated) => {
						if (authenticated) {
							string leaderBoardID = "";
							if (Instance.Difficulty == 0) {
								leaderBoardID = "CgkIh9beq80REAIQAA";
							}
							else if (Instance.Difficulty == 1) {
								leaderBoardID = "CgkIh9beq80REAIQAQ";
							}
							else if (Instance.Difficulty == 2) {
								leaderBoardID = "CgkIh9beq80REAIQAg";
							}
							else {
								
							}
							if (leaderBoardID != "") {
								Social.ReportScore(currentHighScore,leaderBoardID,(bool success) => {
									
								});
							}
						}
					});
				}
			}
			else if (Application.platform == RuntimePlatform.IPhonePlayer) {
				bool canPost = false;
				if (Social.localUser.authenticated) {
					string leaderBoardID = "";
					if (Instance.Difficulty == 0) {
						leaderBoardID = "herobirdeasy";
					}
					else if (Instance.Difficulty == 1) {
						leaderBoardID = "herobirdnormal";
					}
					else if (Instance.Difficulty == 2) {
						leaderBoardID = "herobirdhard";
					}
					else {
						
					}
					if (leaderBoardID != "") {
						Social.ReportScore(currentHighScore,leaderBoardID,(bool success) => {
							
						});
					}
				}
				else {
					Social.localUser.Authenticate((bool authenticated) => {
						if (authenticated) {
							string leaderBoardID = "";
							if (Instance.Difficulty == 0) {
								leaderBoardID = "herobirdeasy";
							}
							else if (Instance.Difficulty == 1) {
								leaderBoardID = "herobirdnormal";
							}
							else if (Instance.Difficulty == 2) {
								leaderBoardID = "herobirdhard";
							}
							else {
								
							}
							if (leaderBoardID != "") {
								Social.ReportScore(currentHighScore,leaderBoardID,(bool success) => {
									
								});
							}
						}
					});
				}
			}
			else if (Application.platform == RuntimePlatform.WP8Player) {
				PubCenterPlugin.PubCenterInteraction.ReportScore(currentHighScore, Instance.Difficulty);
			}
		}
	}

	public void GetUsed() {
		if (!PlayerPrefs.HasKey ("FirstTimeUsage")) {
			Instance.FirstTimeUsage = true;
		} else {
			Instance.FirstTimeUsage = System.Convert.ToBoolean (PlayerPrefs.GetString ("FirstTimeUsage"));
		}
	}

	public void SetUsed() {
		PlayerPrefs.SetString ("FirstTimeUsage", System.Boolean.FalseString);
	}

	public void TouchedEnemy() {
		Instance.LifeLeft -= 2;
		if (Instance.LifeLeft <= 0) {
			Instance.LifeLeft = 0;
			Instance.GameOver();
		}
		//Debug.Log ("Touched Enemy");
		Instance.ScreenShake (0.3f);
		Instance.PlayBeeHurtSound ();
		Instance.PlayHurtSound ();
		Instance.UpdateLife();
	}

	public void KilledEnemy() {
		Instance.AddPoints (1);
		Instance.UpdateScore ();
	}

	public void TouchedItem(float timeLeft) {
		Instance.AddPoints (timeLeft);
		Instance.PlayScoreSound ();
		Instance.UpdateScore ();
	}

	public void TouchedHeart() {
		Instance.LifeLeft += 2;
		if (Instance.LifeLeft > Instance.MaxLife) {
			Instance.LifeLeft = Instance.MaxLife;
		}
		Instance.PlayLifeUpSound ();
		Instance.UpdateLife ();
	}

	public void ItemTimePassed() {
		Instance.LifeLeft--;
		if (Instance.LifeLeft <= 0) {
			Instance.LifeLeft = 0;
			Instance.GameOver();
		}
		//Debug.Log ("Item Passed");
		Instance.ScreenShake (0.1f);
		Instance.PlayHurtSound ();
		Instance.UpdateLife ();
	}

	public void KillInstantiatedObjects() {
		Transform tform = GameObject.Find ("InstantiatedObjects").transform;
		Destroy (tform.gameObject);
	}

	public void GameOver() {
		//Instance.ShowAds();
		Instance.UpdateHighScoreOnGameOver ();

		GameObject.Destroy (Instance.GameScripts);
		Instance.KillInstantiatedObjects ();

		//Instance.ResetGame ();
		//Instance.StartGame ();
		Instance.gameOverEffectsTimer = Instance.gameOverMaxEffectsTimer;
		Instance.gameOverTimer = Instance.gameOverMaxTimer;
		if (Instance.gameOverTextMesh == null) {
			Instance.gameOverTextMesh = (TextMesh)GameObject.Find("GameOverText").GetComponent(typeof(TextMesh));
		}
		Instance.hasGameOvered = true;
		//Application.LoadLevel (0);
	}

	public void ResetGame() {
		if (Application.platform == RuntimePlatform.Android) {
			if (!Instance.AndroidSocialActivated) {
				Instance.AndroidSocialActivated = true;
				GooglePlayGames.PlayGamesPlatform.Activate();
			}
		}

		GameObject.DontDestroyOnLoad ((GameObject)TheGame);
		Instance.LoadSounds ();
		Instance.LifeLeft = Instance.MaxLife;

		if (PlayerPrefs.HasKey ("Difficulty")) {
			Instance.Difficulty = PlayerPrefs.GetInt("Difficulty");
			switch(Instance.Difficulty) {
				case 0: Instance.MaxLife = 14; Instance.LifeLeft = 14; break;
				case 1: Instance.MaxLife = 14; Instance.LifeLeft = 14; break;
				case 2: Instance.MaxLife = 10; Instance.LifeLeft = 10; break;
			}
		}
		else {
			Instance.Difficulty = 1;
			Instance.MaxLife = 14; 
			Instance.LifeLeft = 14;
			PlayerPrefs.SetInt("Difficulty",Instance.Difficulty);
		}
		if (PlayerPrefs.HasKey ("SoundVolume")) {
			Instance.SoundVolume = PlayerPrefs.GetInt("SoundVolume");
			foreach(GameObject obj in Instance.sounds) {
				if (obj != null) {
					AudioSource src = (AudioSource)obj.audio;
					src.volume = Mathf.Lerp(0f,1f,(float)Instance.SoundVolume / 10.0f);
				}
			}
		}
		else {
			Instance.SoundVolume = 10;
			PlayerPrefs.SetInt("SoundVolume",Instance.SoundVolume);
			foreach(GameObject obj in Instance.sounds) {
				if (obj != null) {
					AudioSource src = (AudioSource)obj.audio;
					src.volume = 1f;
				}
			}
		}
		if (PlayerPrefs.HasKey ("MusicVolume")) {
			Instance.MusicVolume = PlayerPrefs.GetInt("MusicVolume");
			AudioSource mainMusic = (AudioSource)GameObject.Find("MainMusic").audio;
			mainMusic.volume = Mathf.Lerp(0.0f,0.3f,(float)Instance.MusicVolume / 10.0f);
		}
		else {
			Instance.MusicVolume = 10;
			PlayerPrefs.SetInt("MusicVolume",Instance.MusicVolume);
			AudioSource mainMusic = (AudioSource)GameObject.Find("MainMusic").audio;
			mainMusic.volume = 0.3f;
		}


		Instance.Score = 0;
		Instance.GetHighScore ();
		Instance.GetUsed ();
		//Instance.CloseAds ();

		//GameObject birdObject = GameObject.Find ("MainBird");
		//GameObject.Destroy (birdObject);

		if (Instance.GameScripts != null) {
			ShootEggsScript shooting = (ShootEggsScript)GameScripts.GetComponent (typeof(ShootEggsScript));
			shooting.Reset ();
		}

		//CloudScroller scroller = (CloudScroller)TheGame.GetComponent (typeof(CloudScroller));
		//scroller.Reset ();

		width = Screen.width;
		height = Screen.height;
		Vector3 result = cam.ScreenToWorldPoint (new Vector3 (width, height, 0f));
		worldX = result.x;
		worldY = result.y;

	}

	void Awake() {
		// First we check if there are any other instances conflicting
		if(Instance != null && Instance != this)
		{
			// If that is the case, we destroy other instances
			Destroy(gameObject);
		}

		// Here we save our singleton instance
		Instance = this;
		
		// Furthermore we make sure that we don't destroy between scenes (this is optional)
		DontDestroyOnLoad(gameObject);
	}

	// Use this for initialization
	void Start () {
		/* GameObject.DontDestroyOnLoad ((GameObject)GameObject.Find ("BirdSprite2_0")); */
		//Instance.CloseAds ();
		Instance.ResetGame ();

		Instance.StartGame ();

	}

	void HandleNoFill (object sender, System.EventArgs e)
	{
		//eventString = "HandleNoFill";
	}
	
	void HandleAdError (object sender, System.EventArgs e)
	{
		//eventString = "HandleAdError";
	}
	
	void HandleAdClosed (object sender, System.EventArgs e)
	{
		//eventString = "HandleAdClosed";
		
		//vservPlugin = new VservWP8Plugin ();
		//Application.LoadLevel (0);
		Instance.CloseAds ();
	}

	public void CloseAds() {
		Instance.triggerAdClose = true;
		//if (Instance.AdOpened != null) {
		//}
	}

	public void CloseInterstitialAds() {
		Instance.triggerInterstitialAdClose = true;
	}

	public void ShowAds() {
		Instance.triggerAdOpen = true;
		//Debug.Log ("HERE");
		//if (Instance.AdOpened != null) {
			//Debug.Log("WTF");
		//}
	}

	public void ShowInterstitialAds() {
		Instance.triggerInterstitialAdOpen = true;
	}

	void GetHeartObjects() {
		Instance.emptyHeartObject = (GameObject)GameObject.Find ("HeartEmpty");
		Instance.halfHeartObject = (GameObject)GameObject.Find ("HeartHalf");
		Instance.fullHeartObject = (GameObject)GameObject.Find ("HeartFull");

	}

	public void StartGame() {
		Instance.GetHeartObjects ();

		if (Application.loadedLevel == 1) {
			Instance.UpdateLife ();
			Instance.UpdateScore ();

			//Instance.CloseAds();
		}
	}

	void AdOpenedMethod(bool setads) {
	}

	public class SpriteBoundsSplitViewModel
	{
		public float ActualDistance {get;set;}
		public float RelativeDistance { get; set; }
		public int SegmentNumber {get;set;}
	}
	
	public void SetInitialRendererPosition(SpriteRenderer sliderRenderer, SpriteRenderer barRenderer, int segments, int segmentNumber) {
		Vector3 minBounds = Camera.main.WorldToScreenPoint(barRenderer.bounds.min);
		Vector3 maxBounds = Camera.main.WorldToScreenPoint(barRenderer.bounds.max);
		
		Vector3 minSliderBounds = Camera.main.WorldToScreenPoint(sliderRenderer.bounds.min);
		Vector3 maxSliderBounds = Camera.main.WorldToScreenPoint(sliderRenderer.bounds.max);
		float sliderDistance = maxSliderBounds.x - minSliderBounds.x;
		float totalDistance = (maxBounds.x - sliderDistance) - minBounds.x;
		float lengthPerSegment = (totalDistance) / (float)segments;
		float halfLengthPerSegment = lengthPerSegment / 2.0f;
		float posDistance = 0f;
		if (segmentNumber == 0)	posDistance = minBounds.x;
		else if (segmentNumber == segments) posDistance = minBounds.x + totalDistance;
		else {
			posDistance = minBounds.x + ((float)segmentNumber * lengthPerSegment);
		}
		
		Vector3 posSlide = sliderRenderer.transform.position;
		Vector3 testVector = Vector3.zero;
		testVector.x = posDistance;
		Vector3 newVector = Camera.main.ScreenToWorldPoint(testVector);
		posSlide.x = newVector.x;
		
		sliderRenderer.transform.position = posSlide;
		//float posDistance = positionToCheck.x - minBounds.x;
	}

	private SpriteBoundsSplitViewModel GetSliderPositionUnsegmented(SpriteRenderer sliderRenderer, SpriteRenderer barRenderer, Vector3 positionToCheck, Vector3 startedPosition, int threshold) {
		Vector3 minBounds = Camera.main.WorldToScreenPoint(barRenderer.bounds.min);
		Vector3 maxBounds = Camera.main.WorldToScreenPoint(barRenderer.bounds.max);
		
		Vector3 minSliderBounds = Camera.main.WorldToScreenPoint(sliderRenderer.bounds.min);
		Vector3 maxSliderBounds = Camera.main.WorldToScreenPoint(sliderRenderer.bounds.max);
		float sliderDistance = maxSliderBounds.x - minSliderBounds.x;
		SpriteBoundsSplitViewModel vm = new SpriteBoundsSplitViewModel ();

		//if (positionToCheck.y >= minSliderBounds.y - threshold && positionToCheck.y <= maxSliderBounds.y + threshold && startedPosition.y >= minSliderBounds.y - threshold && startedPosition.y <= maxSliderBounds.y + threshold) {
		if (startedPosition.y >= minSliderBounds.y - threshold && startedPosition.y <= maxSliderBounds.y + threshold) {
			//Application.LoadLevel(1);
			
			float totalDistance = (maxBounds.x - sliderDistance) - minBounds.x;
			float posDistance = positionToCheck.x - minBounds.x;

			if (positionToCheck.x < minBounds.x) {
				vm.ActualDistance = minBounds.x;
				vm.RelativeDistance = 0f;
				vm.SegmentNumber = 0;
				return vm;
			}
			else if (positionToCheck.x > maxBounds.x - sliderDistance) { 
				vm.ActualDistance = maxBounds.x - sliderDistance;
				vm.RelativeDistance = 1.0f;
				vm.SegmentNumber = 0;
				return vm;
			}

			vm.ActualDistance = positionToCheck.x;
			vm.RelativeDistance = posDistance / totalDistance;
			vm.SegmentNumber = 0;
			return vm;
		}
		else if (positionToCheck.x < minBounds.x) {
			vm.ActualDistance = minBounds.x;
			vm.RelativeDistance = 0f;
			vm.SegmentNumber = 0;
			return vm;
		}
		else if (positionToCheck.x > maxBounds.x) { 
			vm.ActualDistance = maxBounds.x - sliderDistance;
			vm.RelativeDistance = 1.0f;
			vm.SegmentNumber = 0;
			return vm;
		}
		vm.SegmentNumber = -1;
		return vm;
	}

	private SpriteBoundsSplitViewModel GetSliderPositionUnsegmentedVertical(SpriteRenderer sliderRenderer, SpriteRenderer barRenderer, Vector3 positionToCheck, Vector3 startedPosition, int threshold) {
		Vector3 minBounds = Camera.main.WorldToScreenPoint(barRenderer.bounds.min);
		Vector3 maxBounds = Camera.main.WorldToScreenPoint(barRenderer.bounds.max);
		
		Vector3 minSliderBounds = Camera.main.WorldToScreenPoint(sliderRenderer.bounds.min);
		Vector3 maxSliderBounds = Camera.main.WorldToScreenPoint(sliderRenderer.bounds.max);
		float sliderDistance = maxSliderBounds.y - minSliderBounds.y;
		SpriteBoundsSplitViewModel vm = new SpriteBoundsSplitViewModel ();
		
		//if (positionToCheck.y >= minSliderBounds.y - threshold && positionToCheck.y <= maxSliderBounds.y + threshold && startedPosition.y >= minSliderBounds.y - threshold && startedPosition.y <= maxSliderBounds.y + threshold) {
		if (startedPosition.x >= minSliderBounds.x - threshold && startedPosition.x <= maxSliderBounds.x + threshold) {
			//Application.LoadLevel(1);
			
			float totalDistance = (maxBounds.y - sliderDistance) - minBounds.y;
			float posDistance = positionToCheck.y - minBounds.y;
			
			if (positionToCheck.y < minBounds.y) {
				vm.ActualDistance = minBounds.y;
				vm.RelativeDistance = 0f;
				vm.SegmentNumber = 0;
				return vm;
			}
			else if (positionToCheck.y > maxBounds.y) { 
				vm.ActualDistance = maxBounds.y;
				vm.RelativeDistance = 1.0f;
				vm.SegmentNumber = 0;
				return vm;
			}
			
			vm.ActualDistance = positionToCheck.y;
			vm.RelativeDistance = posDistance / totalDistance;
			vm.SegmentNumber = 0;
			return vm;
		}
		else if (positionToCheck.y < minBounds.y) {
			vm.ActualDistance = minBounds.y;
			vm.RelativeDistance = 0f;
			vm.SegmentNumber = 0;
			return vm;
		}
		else if (positionToCheck.y > maxBounds.y) { 
			vm.ActualDistance = maxBounds.y;
			vm.RelativeDistance = 1.0f;
			vm.SegmentNumber = 0;
			return vm;
		}
		vm.SegmentNumber = -1;
		return vm;
	}

	private SpriteBoundsSplitViewModel GetSpriteBoundsSplitPosition(SpriteRenderer sliderRenderer, SpriteRenderer barRenderer, Vector3 positionToCheck, Vector3 startedPosition, int segments, int threshold) {
		Vector3 minBounds = Camera.main.WorldToScreenPoint(barRenderer.bounds.min);
		Vector3 maxBounds = Camera.main.WorldToScreenPoint(barRenderer.bounds.max);
		
		Vector3 minSliderBounds = Camera.main.WorldToScreenPoint(sliderRenderer.bounds.min);
		Vector3 maxSliderBounds = Camera.main.WorldToScreenPoint(sliderRenderer.bounds.max);
		float sliderDistance = maxSliderBounds.x - minSliderBounds.x;
		SpriteBoundsSplitViewModel vm = new SpriteBoundsSplitViewModel ();
		
		int totalRelativeSegs = segments + 1;
		//if (positionToCheck.y >= minSliderBounds.y - threshold && positionToCheck.y <= maxSliderBounds.y + threshold && startedPosition.y >= minSliderBounds.y - threshold && startedPosition.y <= maxSliderBounds.y + threshold) {
		if (startedPosition.y >= minSliderBounds.y - threshold && startedPosition.y <= maxSliderBounds.y + threshold) {
			//Application.LoadLevel(1);
			
			float totalDistance = (maxBounds.x - sliderDistance) - minBounds.x;
			float posDistance = positionToCheck.x - minBounds.x;
			if (segments > 0) { 
				float lengthPerSegment = (totalDistance) / (float)segments;
				float halfLengthPerSegment = lengthPerSegment / 2.0f;
				
				int z = 0;
				int zRel = 0;
				float distTravelled = 0f;
				float distTravelledRelative = 0f;
				
				int numInnerRelativeSegments = segments - 1;
				if (posDistance < halfLengthPerSegment) {
					vm.SegmentNumber = 0;
					vm.ActualDistance = minBounds.x;
					vm.RelativeDistance = minBounds.x;
					return vm;
				}
				if (posDistance >= totalDistance - halfLengthPerSegment) {
					vm.SegmentNumber = segments;
					vm.ActualDistance = minBounds.x + totalDistance;
					vm.RelativeDistance = minBounds.x + totalDistance;
					return vm;
				}
				for (int z2=1;z2<totalRelativeSegs;z2++) {
					float distanceLeft = halfLengthPerSegment + ((float)(z2-1) * lengthPerSegment);
					float distanceRight = halfLengthPerSegment + ((float)(z2) * lengthPerSegment);
					if (posDistance >= distanceLeft && posDistance < distanceRight) {
						vm.SegmentNumber = z2;
						vm.ActualDistance = minBounds.x + distanceLeft + ((distanceRight - distanceLeft) / 2.0f);
						vm.RelativeDistance = minBounds.x + distanceLeft;
						return vm;
					}
				}
			} 
			else {
				vm.ActualDistance = minBounds.x;
				vm.RelativeDistance = minBounds.x;
				vm.SegmentNumber = 0;
				return vm;
			}
		}
		else if (positionToCheck.x < minBounds.x) {
			vm.ActualDistance = minBounds.x;
			vm.RelativeDistance = minBounds.x;
			vm.SegmentNumber = 0;
			return vm;
		}
		else if (positionToCheck.x > maxBounds.x - sliderDistance) { 
			vm.ActualDistance = maxBounds.x - sliderDistance;
			vm.RelativeDistance = maxBounds.x - sliderDistance;
			vm.SegmentNumber = segments;
			return vm;
		}
		vm.SegmentNumber = -1;
		return vm;
	}
	
	public SpriteBoundsSplitViewModel CheckBar(bool hitTest, bool hitTestBar, SpriteRenderer slideRenderer, SpriteRenderer slideBarRenderer, Vector2 position, Vector2 startingPosition, int segments, int threshold) {
		Vector3 posSlide = slideRenderer.transform.position;
		
		SpriteBoundsSplitViewModel vm = new SpriteBoundsSplitViewModel ();
		vm = GetSpriteBoundsSplitPosition(slideRenderer,slideBarRenderer,position,startingPosition,segments,threshold);
		if (vm.SegmentNumber == -1) {
			return vm;
		}
		
		Vector3 testVector = Vector3.zero;
		testVector.x = vm.ActualDistance;
		Vector3 newVector = Camera.main.ScreenToWorldPoint(testVector);
		posSlide.x = newVector.x;
		
		slideRenderer.transform.position = posSlide;
		return vm;
	}

	public SpriteBoundsSplitViewModel CheckBarNoSplit(bool hitTest, bool hitTestBar, SpriteRenderer slideRenderer, SpriteRenderer slideBarRenderer, Vector2 position, Vector2 startingPosition, int threshold) {
		Vector3 posSlide = slideRenderer.transform.position;
		
		SpriteBoundsSplitViewModel vm = new SpriteBoundsSplitViewModel ();
		vm = GetSliderPositionUnsegmented(slideRenderer,slideBarRenderer,position,startingPosition,threshold);
		if (vm.SegmentNumber == -1) {
			return vm;
		}
		
		Vector3 testVector = Vector3.zero;
		testVector.x = vm.ActualDistance;
		Vector3 newVector = Camera.main.ScreenToWorldPoint(testVector);
		posSlide.x = newVector.x;
		
		slideRenderer.transform.position = posSlide;
		return vm;
	}

	public SpriteBoundsSplitViewModel CheckBarNoSplitVertical(bool hitTest, bool hitTestBar, SpriteRenderer slideRenderer, SpriteRenderer slideBarRenderer, Vector2 position, Vector2 startingPosition, int threshold) {
		Vector3 posSlide = slideRenderer.transform.position;
		
		SpriteBoundsSplitViewModel vm = new SpriteBoundsSplitViewModel ();
		vm = GetSliderPositionUnsegmentedVertical(slideRenderer,slideBarRenderer,position,startingPosition,threshold);
		if (vm.SegmentNumber == -1) {
			return vm;
		}
		
		Vector3 testVector = Vector3.zero;
		testVector.y = vm.ActualDistance;
		Vector3 newVector = Camera.main.ScreenToWorldPoint(testVector);
		posSlide.y = newVector.y;
		
		slideRenderer.transform.position = posSlide;
		return vm;
	}

	public bool CheckButton(bool inButton, bool inButtonInitially, SpriteRenderer buttonRenderer, Animator buttonAnimator, MenuButtonConstants.MenuConstants downState, MenuButtonConstants.MenuConstants upState, string intName) {

		if (Instance.ClickDown) {
			if (inButton && inButton) {
				buttonAnimator.SetInteger (intName, (int)downState);
			}
			else {
				buttonAnimator.SetInteger (intName, (int)upState);
			}

		}
		else if (Instance.Moved) {
			if (inButton && inButtonInitially) {
				
				if (buttonAnimator.GetInteger(intName) == (int)downState && !inButton) {
					buttonAnimator.SetInteger (intName, (int)upState);
				}
				else if (buttonAnimator.GetInteger(intName) == (int)upState && inButton) {
					buttonAnimator.SetInteger (intName, (int)downState);
				}
				
			}
			else if (!inButton) {
				buttonAnimator.SetInteger (intName, (int)upState);
			}
		}
		else if (Instance.ClickUp) {
			if (inButton && inButtonInitially) {
				return true;
			}
			else {
				buttonAnimator.SetInteger (intName, (int)upState);
			}

		}
		return false;
	}

	public bool CheckInTouchInteractionState() {
		if (Instance.ClickDown || Instance.Moved || Instance.ClickUp) {
			return true;
		}
		return false;
	}



	
	// Update is called once per frame
	void Update () {
		Instance.ClickEvent = false;
		Instance.ClickDown = false;
		Instance.ClickUp = false;
		Instance.Moved = false;
		Instance.BackButtonPressed = false;
		if (Input.GetKeyUp (KeyCode.Escape)) {
			// Back Button
			Instance.BackButtonPressed = true;
		}

		if (Input.touchCount > 0) {
			//Debug.Log ("TOUCH");
			Touch letouch = Input.GetTouch(0);
			Instance.Pos = letouch.position;
			Instance.CurrentFingerId = letouch.fingerId;
			if (letouch.phase == TouchPhase.Began) {
				Instance.ClickEvent = true;
				//Debug.Log("TOUCH BEGAN");
				if (!Instance.AlreadyClicked) { 
					Instance.ClickDown = true;
					Instance.AlreadyClicked = true;
					Instance.ClickDownPos = Instance.Pos;
					Instance.StartFingerId = letouch.fingerId;
				}
				else { 
					Instance.ClickDown = true;
					Instance.AlreadyClicked = false;
				}
			}
			else if (letouch.phase == TouchPhase.Stationary) {
				Instance.ClickDown = true;
				Instance.AlreadyClicked = false;
			}
			else if (letouch.phase == TouchPhase.Moved) {
				Instance.Moved = true;
			}
			else if (letouch.phase == TouchPhase.Ended || letouch.phase == TouchPhase.Canceled) {
				//Debug.Log("TOUCH ENDED");
				Instance.ClickDown = false;
				Instance.AlreadyClicked = false;
				Instance.ClickUp = true;
			}
		}
		else if (Input.GetMouseButtonDown (0)) {
			Instance.Pos = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
			//Debug.Log("MOUSE DOWN");
			Instance.ClickEvent = true;
			if (!Instance.AlreadyClicked) { 
				Instance.ClickDown = true;
				Instance.AlreadyClicked = true;
				Instance.ClickDownPos = Instance.Pos;
			}
			else { 
				Instance.ClickDown = true;
				Instance.AlreadyClicked = false;
			}
		} else if (Input.GetMouseButtonUp (0)) {
			Instance.Pos = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
			//Debug.Log("MOUSE UP");
			Instance.ClickDown = false;
			Instance.AlreadyClicked = false;
			Instance.ClickUp = true;
			//alreadyClicked = false;
		} else if (Input.GetMouseButton(0)) {
			Instance.Pos = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
			Instance.Moved = true;
		} 

		if (Instance.BackButtonPressed) {

			/*
			if (Application.loadedLevel == 1) {
			Instance.PauseTimeNow = DateTime.Now;
			Instance.PauseTimeStart = Instance.PauseTimeNow;

			if (!Instance.IsPaused) {
				//Time.timeScale = 0.5f;
				//Time.timeScale = 0.25f;
				//Instance.IsPaused = true;



				if (!Instance.IsPausing) {
					Instance.IsPausing = true;
					Instance.IsUnpausing = false;
					Instance.PauseTimeStart = DateTime.Now;
					Instance.PauseTimer = Instance.PauseStartTimer;
				}

			}
			else {
				//Time.timeScale = 1f;
				//Instance.IsPaused = false;


				if (!Instance.IsUnpausing) {
					Instance.IsUnpausing = true;
					Instance.IsPausing = false;
					Instance.PauseTimeStart = DateTime.Now;
					Instance.PauseTimer = Instance.PauseStartTimer;
				}


			}


			}
			*/
		}

		/*
		if (Instance.IsPausing) {
			Instance.PauseTimeNow = DateTime.Now;
			if (Instance.PauseTimer > 0f) {
				Instance.PauseTimer -= Time.deltaTime;
				float slowTimer = Mathf.Lerp(1f,0.1f,(Instance.PauseStartTimer - Instance.PauseTimer) / Instance.PauseStartTimer);
				if (slowTimer == 0.1f) {
					slowTimer = 0f;
				}
				Time.timeScale = slowTimer;

			}
			else {
				Instance.IsPaused = true;
				Instance.IsPausing = false;
				Time.timeScale = 0f;
			}
		}
		if (Instance.IsUnpausing) {
			Instance.PauseTimeNow = DateTime.Now;
			if (Instance.PauseTimer > 0f) {
				Instance.PauseTimer -= Time.deltaTime;
				float speedUpTimer = 1f;

				Time.timeScale = speedUpTimer;

			}
			else {
				Instance.IsPaused = false;
				Instance.IsUnpausing = false;
				Time.timeScale = 1f;
			}
		}
		*/


		if (Instance.ShakeTime >= 0.0f) {
			Instance.ShakeTime -= Time.deltaTime;
			float lerpedShake = Mathf.Lerp(0f, 1f, Instance.ShakeTime / Instance.StartedShakeTime);
			float deltaShake = Mathf.PerlinNoise (lerpedShake, lerpedShake) * 0.33f;
			Vector3 pos = cam.transform.position;
			pos.x = deltaShake;
			pos.y = deltaShake;
			cam.transform.position = pos;
		} else {
			if (cam.transform.position.x != 0f || cam.transform.position.y != 0f) {
				Vector3 pos = cam.transform.position;
				pos.x = 0f;
				pos.y = 0f;
				cam.transform.position = pos;
			}
		}

		if (Instance.hasGameOvered) {
			if (Instance.gameOverTimer < 0f) {
				Instance.hasGameOvered = false;
				// Return to Title
				Application.LoadLevel(0);
				//Application.LoadLevel(3);
			}
			else {
				Instance.gameOverTimer -= Time.deltaTime;
				Instance.gameOverEffectsTimer -= Time.deltaTime;
				if (Instance.gameOverEffectsTimer < 0f) {
					Instance.gameOverEffectsTimer = 0f;
				}
				float gameOverMinY = -6.28f;
				float gameOverMaxY = 0.8f;

				float currentY = Mathf.Lerp(gameOverMinY, gameOverMaxY, 1f - Instance.gameOverEffectsTimer / Instance.gameOverMaxEffectsTimer);
				float alpha = Mathf.Lerp(0f, 1f, 1f - Instance.gameOverEffectsTimer / Instance.gameOverMaxEffectsTimer);
				Vector3 pos = Instance.gameOverTextMesh.gameObject.transform.position;
				pos.y = currentY;
				Instance.gameOverTextMesh.gameObject.transform.position = pos;
				Color col = Instance.gameOverTextMesh.color;
				col.a = alpha;
				Instance.gameOverTextMesh.color = col;
			}
		}
	}

	void UpdateScore() {
		Transform textTrans = GameObject.Find ("ScoreText").gameObject.transform;
		Vector3 pos = textTrans.position;
		float yPosition = worldY - 0.0f;
		float xPositionText = worldX - 0f;
		pos.y = yPosition;
		pos.x = xPositionText;
		textTrans.position = pos;
		TextMesh tMesh = (TextMesh)textTrans.gameObject.GetComponent (typeof(TextMesh));
		tMesh.text = "Score: " + Instance.Score.ToString () + "\n" + "High Score: " + Instance.HighScore.ToString();
	}

	void LoadSounds() {
		Instance.sounds = new GameObject[7];
		sounds[0] = GameObject.Find ("WaspSting");
		sounds[1] = GameObject.Find ("WaspSting");
		sounds[2] = GameObject.Find ("HurtSound");
		sounds[3] = GameObject.Find ("GrabEnergy");
		sounds[4] = GameObject.Find ("BombDefuse");
		sounds[5] = GameObject.Find ("BirdFlap");
		sounds [6] = GameObject.Find ("BombTick");
	}

	void OnGUI() {
		if (Instance.DebugText != string.Empty) {
			GUI.Label(new Rect(20,20,500,200), new GUIContent(Instance.DebugText));
		}
		if (Instance.triggerAdOpen) {
			Instance.triggerAdOpen = false;

			try {
				if (Application.platform == RuntimePlatform.WP8Player || Application.platform == RuntimePlatform.MetroPlayerARM || Application.platform == RuntimePlatform.MetroPlayerX86 || Application.platform == RuntimePlatform.MetroPlayerX64) {
					PubCenterPlugin.PubCenterInteraction.ShowAds();
				}
				
				else if (Application.platform == RuntimePlatform.Android) {
					/*
					if (Instance.bannerView == null) {
						try {
							Instance.bannerView.horizontalPosition = AdHorizontalPosition.CENTER_HORIZONTAL;
							Instance.bannerView.verticalPosition = AdVerticalPosition.BOTTOM;
							Instance.bannerView.orientation = AdOrientation.HORIZONTAL;
							Instance.bannerView.publisherId = "ca-app-pub-7664787518361934/4009553208";
							Instance.bannerView.size = AdSize.BANNER;
							Instance.bannerView.loadOnStart = true;
							Instance.bannerView.isTesting = false;
							Instance.bannerView.Reconfigure();
							Instance.bannerView.Load();
							Instance.bannerView.Show();
						}
						catch {

						}
					}
					else {
						Instance.bannerView.horizontalPosition = AdHorizontalPosition.CENTER_HORIZONTAL;
						Instance.bannerView.verticalPosition = AdVerticalPosition.BOTTOM;
						Instance.bannerView.orientation = AdOrientation.HORIZONTAL;
						Instance.bannerView.publisherId = "ca-app-pub-7664787518361934/4009553208";
						Instance.bannerView.size = AdSize.BANNER;
						Instance.bannerView.loadOnStart = true;
						Instance.bannerView.isTesting = false;
						Instance.bannerView.Reconfigure();
						Instance.bannerView.Load();
						Instance.bannerView.Show();
					}
					*/
				}
				else if (Application.platform == RuntimePlatform.IPhonePlayer) {
#if UNITY_IPHONE && !UNITY_EDITOR
					if (Instance.iosBannerView == null) {
						Instance.iosBannerView = new ADBannerView(ADBannerView.Type.Banner,ADBannerView.Layout.Bottom);
					}
					Instance.iosBannerView.visible = true;
#endif
				}
				//AdOpened(true);
			}
			catch {
			}
			
			Instance.isAdOpened = true;

		} else if (Instance.triggerAdClose) {
			Instance.triggerAdClose = false;

			try {
				if (Application.platform == RuntimePlatform.WP8Player || Application.platform == RuntimePlatform.MetroPlayerARM || Application.platform == RuntimePlatform.MetroPlayerX86 || Application.platform == RuntimePlatform.MetroPlayerX64) {
					PubCenterPlugin.PubCenterInteraction.HideAds();
				}
				else if (Application.platform == RuntimePlatform.Android) {
					/*
					try {
						if (Instance.bannerView != null) {
							Instance.bannerView.Hide();
						}
					}
					catch(Exception ex) {
					
					}
					*/
				}
				else if (Application.platform == RuntimePlatform.IPhonePlayer) {
#if UNITY_IPHONE && !UNITY_EDITOR
					Instance.iosBannerView.visible = false;
#endif
				}
				//AdOpened(false);
			}
			catch {
			}
			Instance.isAdOpened = false;
		}

		// Try and load this the first go
		if (!Instance.displayedAdsOnce) {
			try
			{
			/*
			if (Instance.vservPlugin != null) {
				Instance.vservPlugin.DisplayAd ("b18b0d95");
				//vservPlugin.RenderAd("28825c2f", 2);
				Instance.vservPlugin.SetRefreshRate(5);
				/*
				1 - Top_Left
				2 - Top_Center
				3 - Top_Right
				4 - Center_Left
				5 - Center
				6 - Center_Right
				7 - Bottom_Left 
				8 - Bottom_Center
				*/
				
				//vservPlugin.DisplayAd("b18b0d95");
				Instance.displayedAdsOnce = true;
			//}

			}
			catch(Exception e)
			{
			}
		}
	}

	void UpdateLife() {
		if (Instance.MaxLife % 2 > 0) {
			Instance.MaxLife++;
		}
		int numHearts = Instance.MaxLife / 2;
		
		// This needs to be dynamimc
		float yPosition = worldY - 0.3f;
		float xPosition = -1f * worldX + 0.3f;
		if (heartObjects != null) {
			for (int z=0;z<heartObjects.Length;z++) {
				if (heartObjects[z] != null) {
					GameObject.Destroy(heartObjects[z]);
				}
			}
		}
		heartObjects = new GameObject[numHearts];

		if (Instance.halfHeartObject == null || Instance.fullHeartObject == null || Instance.emptyHeartObject == null) {
			Instance.GetHeartObjects();
		}

		for (int z=0;z<numHearts;z++) {
			Vector3 pos = new Vector3(xPosition, yPosition, 0f);
			xPosition += 0.65579f;

			if (z * 2 + 1 == Instance.LifeLeft) {
				heartObjects[z] = (GameObject)GameObject.Instantiate(Instance.halfHeartObject, pos, Quaternion.identity);
			}
			else if (z * 2 < Instance.LifeLeft) {
				heartObjects[z] = (GameObject)GameObject.Instantiate(Instance.fullHeartObject, pos, Quaternion.identity);
			}
			else {
				heartObjects[z] = (GameObject)GameObject.Instantiate(Instance.emptyHeartObject, pos, Quaternion.identity);
			}


		}

	}
}
